GSaveTool = OpenLayers.Class( {
	
	map : null,

	xml : null,

	style : null,
	
	nXMin : 0,
	
	nXMax : 0,
	
	nYMin : 0,
	
	nYMax : 0,

	initialize : function(map) {
		this.map = map;
	},

	getXML : function() {
		this.xml = "<LAYERS>";
		
		this.parseMap();
		this.parseLayer();
		this.parseVector();
		this.parsePopup();

		this.xml += "</LAYERS>";
		
		return this.xml;
	},
	parseMap : function() {
		this.xml += "<MAP>";
		
		var left = this.map.getExtent().left,
			bottom = this.map.getExtent().bottom,
			right = this.map.getExtent().right,
			top = this.map.getExtent().top;
		
		if("SR-ORG:6640" != gMap.getProjection()) {
			var sourcePrj = new Proj4js.Proj(gMap.getProjection());
			var targetPrj = new Proj4js.Proj("SR-ORG:6640");
			
			var min = new Proj4js.Point(left, bottom);
			var max = new Proj4js.Point(right, top);
			
			Proj4js.transform(sourcePrj, targetPrj, min);
			Proj4js.transform(sourcePrj, targetPrj, max);
			
			left = min.x;
			bottom = min.y;
			right = max.x;
			top = max.y;
		}
		
		var params = {
			left : left,
			bottom : bottom,
			right : right,
			top : top,
			width : this.map.getSize().w,
			height : this.map.getSize().h,
			resolution : this.map.getResolution()
		};

		this.write(params);

		this.xml += "</MAP>";
	},
	
	containNaverTile : function(tileObj, buffer){
		var x = tileObj.css("left").replace("px", "") * 1;
		var y = tileObj.css("top").replace("px", "") * 1;
		
		
		if( (x > this.nXMin - buffer && x < this.nXMax + buffer) && (y > this.nYMin - buffer && y < this.nYMax + buffer) ) {
			return tileObj;
		}
		return null;
	},
	
	parseLayer : function() {
		for ( var i = 0; i < this.map.layers.length; i++) {
			if ((this.map.layers[i].CLASS_NAME == "GWMS" || this.map.layers[i].CLASS_NAME == "OpenLayers.Layer.WMS" || this.map.layers[i].CLASS_NAME == "GWMSPost") && this.map.layers[i].visibility) {
				this.xml += '<LAYER type="wms">';
				
				var params = {
					url : this.map.layers[i].url,
					layers : this.map.layers[i].params.LAYERS,
					styles : this.map.layers[i].params.STYLES,
					format : this.map.layers[i].params.FORMAT,
					version : this.map.layers[i].params.VERSION,
					crs : this.map.layers[i].params.CRS,
					service : this.map.layers[i].params.SERVICE,
					request : this.map.layers[i].params.REQUEST,
					exceptions : this.map.layers[i].params.EXCEPTIONS,
					opacity : this.map.layers[i].opacity
				};
				
				if(this.map.layers[i].params.SLD_BODY) {
					params.sldbody = this.map.layers[i].params.SLD_BODY;
				};
				
				this.write(params);

				this.xml += "</LAYER>";
			}
			else if (this.map.layers[i].CLASS_NAME == "GTileCache" && this.map.layers[i].visibility) {
				this.xml += '<LAYER type="tilecache">';

				params = {
					url : this.map.layers[i].url,
					layername : this.map.layers[i].layername,
					scaleLevel : this.map.getZoom()+2,
					maxLeft : this.map.layers[i].maxExtent.left,
					maxBottom : this.map.layers[i].maxExtent.bottom,
					maxRight : this.map.layers[i].maxExtent.right,
					maxTop : this.map.layers[i].maxExtent.top,
			//		extension : "."+ this.map.layers[i].format.split('/')[1].toLowerCase()
				};

				this.write(params);

				this.xml += "</LAYER>";
			}
			else if ( (this.map.layers[i].CLASS_NAME == "OpenLayers.Layer.NaverStreet" || this.map.layers[i].CLASS_NAME == "OpenLayers.Layer.NaverSatellite")) {
				
				var tileImages = $("#naverMap .nmap_base_pane").find("img");
				var id = this.map.layers[i].id;
				var $mapContainer = $("#" + id).parent();
				var mapLeft = $mapContainer.css("left").replace("px", "") * 1;
				var mapTop = $mapContainer.css("top").replace("px", "") * 1;
				
				var nMapWidth = $("#naverMap").css("width").replace("px", "") * 1;
				var nMapHeight = $("#naverMap").css("height").replace("px", "") * 1;
				
				/*var nMapWidth = Math.sqrt($("#naverMap .nmap_base_pane").find("img").length) * 256;
				var nMapHeight = Math.sqrt($("#naverMap .nmap_base_pane").find("img").length) * 256;*/
				
				var gMapWidth = gMap.getSize().w;
				var gMapHeight = gMap.getSize().h;
				
				this.nXMin = (nMapWidth / 2) - (gMapWidth / 2); // left
				this.nXMax = this.nXMin + gMapWidth; // right
				this.nYMin = (nMapHeight / 2) - (gMapHeight / 2); // top
				this.nYMax =  this.nYMin + gMapHeight; // bottom
				
				/*var nMapLeft = (nMapWidth / 2) - (gMapWidth / 2);
				var nMapRight = nMapLeft + gMapWidth;
				var nMapTop = (nMapHeight / 2) - (gMapHeight / 2);
				var nMapBottom = nMapTop + gMapHeight;
				*/
				if(tileImages.length < 1) continue;
				
				this.xml += '<LAYER type="naverStreet">';
				
				var tile = [];
				
				for(var j = 0; j < tileImages.length; j++) {
					var tileObj = this.containNaverTile($(tileImages[j]), 500);
					if(tileObj) {
						var x = (tileObj.css("left").replace("px", "") * 1) - Math.round(this.nXMin);
						var y = (tileObj.css("top").replace("px", "") * 1) - Math.round(this.nYMin);
						
						tile.push({
							url : $(tileImages[j]).attr("src"),
							x : x + mapLeft,
							y : y + mapTop
						});
					}
				}
				params = {
					tile : tile
				};
				
				this.write(params);
				this.xml += "</LAYER>";
			}
			else if(this.map.layers[i].CLASS_NAME == "OpenLayers.Layer.ArcGISCache" && this.map.layers[i].visibility) {
				this.xml += '<LAYER type="ArcGISCache">';
				
				var res = this.map.layers[i].getResolution();
				var start = this.map.layers[i].getUpperLeftTileCoord(res);
		        var end = this.map.layers[i].getLowerRightTileCoord(res);

		        var numTileCols = (end.x - start.x) + 1;
		        var numTileRows = (end.y - start.y) + 1;
				params = {
					url : this.map.layers[i].url,
					tileOriginLon : this.map.layers[i].tileOrigin.lon,
					tileOriginLat : this.map.layers[i].tileOrigin.lat,
					minRows : numTileRows,
					minCols : numTileCols,
					centerX : this.map.getExtent().getCenterLonLat().lon,
					centerY : this.map.getExtent().getCenterLonLat().lat,
					scaleLevel : this.map.getZoom(),
					maxLeft : this.map.layers[i].maxExtent.left,
					maxBottom : this.map.layers[i].maxExtent.bottom,
					maxRight : this.map.layers[i].maxExtent.right,
					maxTop : this.map.layers[i].maxExtent.top
				};
				this.write(params);
				this.xml += "</LAYER>";
			}
		}
	},

	parseVector : function() {
		for(var i=0; i < this.map.layers.length; i++) {
			if(this.map.layers[i].CLASS_NAME == "GVector" && this.map.layers[i].visibility) {
				
				this.xml += "<VECTORLAYER>";
				for(var j=0; j < this.map.layers[i].features.length; j++) {
					if(this.map.layers[i].features[j].geometry.CLASS_NAME == "OpenLayers.Geometry.Point") {
						if(!this.map.layers[i].features[j].attributes.featureType) {
							continue;
						}
						
						var params;
						var style = this.map.layers[i].parseStyle(this.map.layers[i].features[j]);
						
						if(this.map.layers[i].features[j].attributes.featureType == "Image") {
							params = {
								x : this.map.layers[i].features[j].geometry.x,
								y : this.map.layers[i].features[j].geometry.y,
								featureType : this.map.layers[i].features[j].attributes.featureType,
								opacity : style.graphicOpacity,
								width : style.graphicWidth,
								height : style.graphicHeight,
								image : style.externalGraphic
							};
						}
						else if (this.map.layers[i].features[j].attributes.featureType == "Point") {
							
							if(!(style.graphicName == "circle" || style.graphicName == "square")) {
								style.graphicName == "circle";
							}
							
							params = {
								x : this.map.layers[i].features[j].geometry.x,
								y : this.map.layers[i].features[j].geometry.y,
								featureType : this.map.layers[i].features[j].attributes.featureType,
								radius : style.pointRadius,
								graphicName : style.graphicName,
								stroke : style.strokeWidth,
								color : style.strokeColor,
								opacity : style.strokeOpacity,
								fillColor : style.fillColor,
								fillOpacity : style.fillOpacity
							};
						}
						
						this.xml += '<FEATURE type="point">';
						
						this.write(params);
						
						this.xml += "</FEATURE>";
					}
					else if(this.map.layers[i].features[j].geometry.CLASS_NAME == "OpenLayers.Geometry.LineString") {
						
						var style = this.map.layers[i].parseStyle(this.map.layers[i].features[j]);

						if(this.map.layers[i].features[j].attributes.featureType == "arrow") {
							this.xml += '<FEATURE type="arrow">';
						}
						else {
							this.xml += '<FEATURE type="lineString">';
						}

						var x = [];
						var y = [];

						for(var k = 0; k < this.map.layers[i].features[j].geometry.components.length; k++) {
							x.push(this.map.layers[i].features[j].geometry.components[k].x);
							y.push(this.map.layers[i].features[j].geometry.components[k].y);
						}

						var params = {
							x : x,
							y : y,
							color : style.strokeColor,
							opacity : style.strokeOpacity,
							stroke : style.strokeWidth,
							strokeDashstyle : style.strokeDashstyle,
							strokeLinecap : style.strokeLinecap
						};

						this.write(params);

						this.xml += "</FEATURE>";
					}
					else if(this.map.layers[i].features[j].geometry.CLASS_NAME == "OpenLayers.Geometry.Polygon") {
						var style = this.map.layers[i].parseStyle(this.map.layers[i].features[j]);
						
						this.xml += '<FEATURE type="polygon">';

						var x = [];
						var y = [];

						for(var k = 0; k < this.map.layers[i].features[j].geometry.components[0].components.length; k++) {
							x.push(this.map.layers[i].features[j].geometry.components[0].components[k].x);
							y.push(this.map.layers[i].features[j].geometry.components[0].components[k].y);
						}
						
						var params = {
							x : x,
							y : y,
							color : style.strokeColor,
							opacity : style.strokeOpacity,
							stroke : style.strokeWidth,
							fillColor : style.fillColor,
							fillOpacity : style.fillOpacity,
							label : style.label,
							fontColor : style.fontColor,
							centerX : this.map.layers[i].features[j].geometry.getCentroid().x,
							centerY : this.map.layers[i].features[j].geometry.getCentroid().y,
							strokeDashstyle : style.strokeDashstyle,
							strokeLinecap : style.strokeLinecap
						};
						
						alert(params.strokeDashstyle);

						this.write(params);

						this.xml += "</FEATURE>";
					}
					else if(this.map.layers[i].features[j].geometry.CLASS_NAME == "OpenLayers.Geometry.MultiPolygon") {
						var style = this.map.layers[i].parseStyle(this.map.layers[i].features[j]);
						
						var feature = this.map.layers[i].features[j];
						
						for(var k=0; k < feature.geometry.components.length; k++) {
							this.xml += '<FEATURE type="polygon">';

							var x = [];
							var y = [];
							
							var polygonComponent = feature.geometry.components[k];
							
							for(var l=0; l < polygonComponent.components[0].components.length; l++) {
								x.push(polygonComponent.components[0].components[l].x);
								y.push(polygonComponent.components[0].components[l].y);
							}
							
							var params = {
								x : x,
								y : y,
								color : style.strokeColor,
								opacity : style.strokeOpacity,
								stroke : style.strokeWidth,
								fillColor : style.fillColor,
								fillOpacity : style.fillOpacity,
								label : style.label,
								fontColor : style.fontColor,
								centerX : this.map.layers[i].features[j].geometry.getCentroid().x,
								centerY : this.map.layers[i].features[j].geometry.getCentroid().y,
								strokeDashstyle : style.strokeDashstyle,
								strokeLinecap : style.strokeLinecap
							};
							
							this.write(params);
							
							this.xml += "</FEATURE>";
						}
					}
				}
				
				this.xml += "</VECTORLAYER>";
			}
		}
	},
	
	parsePopup : function() {
		if(this.map.popups.length > 0) this.xml += "<POPUPS>";
		
		for(var i=0; i < this.map.popups.length; i++) {
			if(this.map.popups[i].attributes && this.map.popups[i].attributes.print) {
				this.xml += "<POPUP>";
				
				if(!this.map.popups[i].attributes.fontFamily) {
					this.map.popups[i].attributes.fontFamily = "굴림";
				}
				if(!this.map.popups[i].attributes.fontSize) {
					this.map.popups[i].attributes.fontSize = "12";
				}
				if(!this.map.popups[i].attributes.fontColor)
					this.map.popups[i].attributes.fontColor = "#000000";
				
				var params = {
					x : this.map.popups[i].lonlat.lon,
					y : this.map.popups[i].lonlat.lat,
					width : $(this.map.popups[i].contentDiv).css("width").replace("px",""),
					height : $(this.map.popups[i].contentDiv).css("height").replace("px",""),
					text : this.map.popups[i].attributes.text,
					fontFamily : this.map.popups[i].attributes.fontFamily,
					fontSize : this.map.popups[i].attributes.fontSize.replace("px", ""),
					fontColor : this.map.popups[i].attributes.fontColor
				};
			
				this.write(params);
				
				this.xml += "</POPUP>";
			}
		}
		
		if(this.map.popups.length > 0) this.xml += "</POPUPS>";
	},

	write : function(obj) {
		for ( var i in obj) {
			var items = obj[i];
			if(items instanceof Object) {
				for(var idx = 0; idx < items.length; idx++) {
					var item = items[idx];
					this.xml += "<tile>";
					
					for (var j in item) {
						this.xml += "<" + j + ">" + encodeURIComponent(item[j])
						+ "</" + j + ">";
					}
					
					this.xml += "</tile>";
				}
			} else {
				this.xml += "<" + i + ">" + encodeURIComponent(obj[i])
				+ "</" + i + ">";
			}
		}
	},

	CLASS_NAME : "GSaveTool"
});